package com.gla.giliair.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gla.giliair.dao.MOrderDao;
import com.gla.giliair.dao.SeatDao;
import com.gla.giliair.entity.Flight;
import com.gla.giliair.entity.MOrder;
import com.gla.giliair.entity.Seat;
import com.gla.giliair.entity.SeatExample;
import com.gla.giliair.service.FlightService;
import com.gla.giliair.service.OrderService;
import com.gla.giliair.service.SeatService;
import com.gla.giliair.util.BeanUtil;
import com.gla.giliair.util.MapGenerator;
import com.gla.giliair.web.vo.SeatVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description:
 * @Author: Yingtian qian
 * @Date: 2021/8/25 20:48
 */
@Service
public class SeatServiceImpl implements SeatService {
    @Autowired
    private SeatDao seatDao;

    @Autowired
    private MOrderDao mOrderDao;

    @Autowired
    private FlightService flightService;

    @Autowired
    private OrderService orderService;

    @Override
    public Seat selectSeatById(Long seatId) {
        if (seatId != null) {
            SeatExample seatExample = new SeatExample();
            seatExample.or().andSeatIdEqualTo(seatId);
            List<Seat> seatList = seatDao.selectByExample(seatExample);
            if (seatList.isEmpty()) {
                return null;
            }
            return seatList.get(0);
        }
        return null;
    }

    @Override
    public List<Seat> selectSeatsByFlightId(Long flightId) {
        if (flightId != null) {
            SeatExample seatExample = new SeatExample();
            seatExample.setOrderByClause("seat_id asc");
            seatExample.or().andFlightIdEqualTo(flightId);
            List<Seat> seatList = seatDao.selectByExample(seatExample);
            return seatList;
        }
        return null;
    }

    @Override
    public Map<String, Object> findSeatsByFlightId(Long flightId, Integer page, Integer pageSize) {
        Flight flightFromDB = flightService.selectFlightById(flightId);
        if (flightFromDB == null) {
            return MapGenerator.getRes(501, "航班不存在！");
        }
        PageHelper.startPage(page, pageSize);
        List<Seat> seatList = selectSeatsByFlightId(flightId);
        PageInfo pageInfo = new PageInfo(seatList);

        if (!seatList.isEmpty()) {
            List<SeatVO> seatVOList = BeanUtil.copyList(seatList, SeatVO.class);
            pageInfo.setList(seatVOList);
            return MapGenerator.getResWithData(200, "获取动态座位列表成功！", pageInfo);
        } else {
            return MapGenerator.getRes(201, "获取结果为空！");
        }
    }

    @Override
    public Map<String, Object> findSeatsWithOrderByFlightIdAndIDNumber(Long flightId, String IDNumber, Integer page, Integer pageSize) {
        Flight flightFromDB = flightService.selectFlightById(flightId);
        if (flightFromDB == null) {
            return MapGenerator.getRes(501, "航班不存在！");
        }
        MOrder mOrder = orderService.selectOrderByIDNumberAndFlightId(IDNumber, flightId);
        if (mOrder == null) {
            return MapGenerator.getRes(502, "查无此订单！");
        }
        if (mOrder.getOrderState() != 1) {
            return MapGenerator.getRes(503, "您的订单状态不为已支付/未选座，不能选座！");
        }

        PageHelper.startPage(page, pageSize);
        List<Seat> seatList = selectSeatsByFlightId(flightId);
        PageInfo pageInfo = new PageInfo(seatList);

        if (!seatList.isEmpty()) {
            List<SeatVO> seatVOList = BeanUtil.copyList(seatList, SeatVO.class);
            pageInfo.setList(seatVOList);

            Map<String, Object> data = new HashMap<>();
            data.put("seatList", pageInfo);
            data.put("order", mOrder);

            return MapGenerator.getResWithData(200, "获取动态座位列表(携带订单)成功！", data);
        } else {
            return MapGenerator.getRes(201, "获取结果为空！");
        }
    }

    @Override
    public Map<String, Object> selectSeat(Seat seat, Long userId) {
        Seat seatFromDB = selectSeatById(seat.getSeatId());
        if (seatFromDB == null) {
            return MapGenerator.getRes(502, "座位不存在！");
        }
        MOrder mOrderFromDB = orderService.selectOrderById(seat.getOrderId());
        if (mOrderFromDB == null) {
            return MapGenerator.getRes(503, "订单号不存在！");
        }
        if (userId != 0) {
            if (!mOrderFromDB.getCustomerId().equals(userId)) {
                return MapGenerator.getRes(504, "无权限选座！");
            }
        }
        if (mOrderFromDB.getOrderState() != 1) {
            return MapGenerator.getRes(505, "订单状态不为已支付/未选座，不能选座！");
        }
        if (seatFromDB.getSeatState() != 0) {
            return MapGenerator.getRes(506, "座位状态不为未被占用，不能选该座位！");
        }
        if (!seatFromDB.getSeatType().equals(mOrderFromDB.getSeatType())) {
            return MapGenerator.getRes(507, "座位类型不一致，不能选该座位！");
        }

        Date nowDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);
        calendar.add(Calendar.MINUTE, 45);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sDateStr = sdf.format(calendar.getTime());
        try {
            Date sDate = sdf.parse(sDateStr);
            if (sDate.after(mOrderFromDB.getLeaveTime())) {
                return MapGenerator.getRes(508, "选座时间截止到起飞前45分钟，已超时，请去机场人工办理手续！");
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Long seatId = seatFromDB.getSeatId();
        Long orderId = mOrderFromDB.getOrderId();
        //订单内座位号为空，且座位内订单号为空，才可以正常选座（前面的验证应该排除了不为双空的可能性）
        if (mOrderFromDB.getSeatId() == null && seatFromDB.getOrderId() == null) {
            mOrderFromDB.setSeatId(seatId);
            mOrderFromDB.setSeatNumber(seatFromDB.getSeatNumber());
            mOrderFromDB.setOrderState(2);
            seatFromDB.setOrderId(orderId);
            seatFromDB.setSeatState(1);
        } else {
            return MapGenerator.getRes(520, "内部错误！");
        }

        if (mOrderDao.updateByPrimaryKeySelective(mOrderFromDB) <= 0) {
            return MapGenerator.getRes(520, "内部错误！");
        }
        if (seatDao.updateByPrimaryKeySelective(seatFromDB) > 0) {
            return MapGenerator.getRes(200, "选座成功！");
        }
        return MapGenerator.getRes(520, "内部错误！");
    }

    @Override
    public Map<String, Object> cancelSeat(Seat seat, Long userId) {
        MOrder mOrderFromDB = orderService.selectOrderById(seat.getOrderId());
        if (mOrderFromDB == null) {
            return MapGenerator.getRes(502, "订单号不存在！");
        }
        if (userId != 0) {
            if (!mOrderFromDB.getCustomerId().equals(userId)) {
                return MapGenerator.getRes(503, "无权限取消选座！");
            }
        }
        if (mOrderFromDB.getOrderState() != 2) {
            return MapGenerator.getRes(504, "订单状态不为已选座，不能取消选座！");
        }
        Date nowDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);
        calendar.add(Calendar.MINUTE, 45);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sDateStr = sdf.format(calendar.getTime());
        try {
            Date sDate = sdf.parse(sDateStr);
            if (sDate.after(mOrderFromDB.getLeaveTime())) {
                return MapGenerator.getRes(505, "取消选座时间截止到起飞前45分钟，已超时，请去机场人工办理手续！");
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Long seatId = mOrderFromDB.getSeatId();
        Seat seatFromDB = selectSeatById(seatId);
        if (seatFromDB == null) {
            return MapGenerator.getRes(520, "内部错误！");
        }
        mOrderFromDB.setSeatId(null);
        mOrderFromDB.setSeatNumber(null);
        mOrderFromDB.setOrderState(1);
        seatFromDB.setOrderId(null);
        seatFromDB.setSeatState(0);

        //不使用updateByPrimaryKeySelective，赋予空值
        if (mOrderDao.updateByPrimaryKey(mOrderFromDB) <= 0) {
            return MapGenerator.getRes(520, "内部错误！");
        }
        if (seatDao.updateByPrimaryKey(seatFromDB) > 0) {
            return MapGenerator.getRes(200, "取消选座成功！");
        }
        return MapGenerator.getRes(520, "内部错误！");
    }

    @Override
    public Map<String, Object> lockSeat(Seat seat) {
        Seat seatFromDB = selectSeatById(seat.getSeatId());
        if (seatFromDB == null) {
            return MapGenerator.getRes(501, "座位不存在！");
        }
        if (seatFromDB.getSeatState() == 0 && seat.getSeatState() == 2) {
            seatFromDB.setSeatState(2);
            if (seatDao.updateByPrimaryKeySelective(seatFromDB) > 0) {
                return MapGenerator.getRes(200, "冻结座位成功！");
            }
            return MapGenerator.getRes(520, "内部错误！");
        }
        if (seatFromDB.getSeatState() == 2 && seat.getSeatState() == 0) {
            seatFromDB.setSeatState(0);
            if (seatDao.updateByPrimaryKeySelective(seatFromDB) > 0) {
                return MapGenerator.getRes(200, "解冻座位成功！");
            }
            return MapGenerator.getRes(520, "内部错误！");
        }
        return MapGenerator.getRes(502, "该座位不能被冻结/解冻，请检查座位状态和输入参数！");
    }
}
